package is.api.demo.isgateway.example.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import is.api.demo.isgateway.support.IsGateWayHttpResponseBody;
import is.api.demo.isgateway.support.IsGatewayApiResponse;
import is.api.demo.isgateway.support.RequestHeader;
import is.api.demo.isgateway.support.ResponseBody;
import is.api.demo.isgateway.utils.IsGateWayHttpClientUtils;
import is.api.demo.isgateway.utils.IsGatewayApiResponseUtils;
import is.api.demo.isgateway.utils.Sm2CertUtils;
import is.api.demo.isgateway.utils.Sm2Utils;
import org.bouncycastle.util.encoders.Hex;

import java.util.*;

/**
 * 此类仅支持 密钥认证模式
 * 需提前完成以下工作：
 * 1、申请获取appid、私钥、公钥、版本号；
 * 2、掌握接口完整路径(接口总线地址[区分局内网、电子政务云、互联网]和接口前端路径),并完成接口赋权(访问权限)；
 *
 * @author huan.lin
 */
public class IsGateWayTestMain {
    //
    private static final ObjectReader objectReader;
    /**
     * 接口总线域名(根路径)[互联网]
     */
    private static String basePath = "http://paasis.funi365.com/isgateway";
    /**
     * 接口资源相对路径(接口前端路径)
     */
    private static String resource = "/100019/pct/admin/findConfigFiles";
    /**
     * 你的账号(appid)
     */
    private static String appKey = "8337664962864545792";
    /**
     * 版本号
     */
    private static String version = "1.0.0";
    /**
     * 公钥
     */
    private static String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEzLOx066MCdxnkA1UVIKXsXmZZxCQpEeiboFxZTRW5gunGounya8F2al0gHcF74STjvM/TD8MiaWM/chG8qITmQ==";
    /**
     * 私钥
     */
    private static String privateKey = "MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgiN7S2+bnJWWtrIHbDYJOn4vS+DpZ1u8UFlcVKR2HvyGhRANCAATMs7HTrowJ3GeQDVRUgpexeZlnEJCkR6JugXFlNFbmC6cai6fJrwXZqXSAdwXvhJOO8z9MPwyJpYz9yEbyohOZ";

    static {
        ObjectMapper objectMapper = new ObjectMapper();
        objectReader = objectMapper.reader();
    }

    /**
     * 创建请求头
     *
     * @return 请求头
     */
    private static Map<String, String> getRequestHeaders() {
        final Map<String, String> headers = new HashMap<String, String>();
        headers.put(RequestHeader.RESOURCE, resource);
        headers.put(RequestHeader.OPEN_APP_KEY, appKey);
        headers.put(RequestHeader.OPEN_REQUEST_ID, UUID.randomUUID().toString());
        headers.put(RequestHeader.OPEN_TIMESTAMP, System.currentTimeMillis() + "");
        headers.put(RequestHeader.OPEN_VERSION, version);
        return headers;
    }

    /**
     * 创建待签名字符串
     *
     * @param params 待签名对象
     */
    public static String createSignContent(Map<String, String> params) {
        final StringBuilder content = new StringBuilder();
        final List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            content.append(i == 0 ? "" : "&").append(key).append("=").append(value);
        }
        return content.toString();
    }

    public static void main(String[] args) throws Exception {
        System.err.println("begin===============================================================");
        //私钥转16进制
        final String privateKeyStrFromPKCS8 = Sm2CertUtils.getPrivateKeyStrFromPKCS8(privateKey);
        //公钥转16进制
        final String publicKeyStrFromX509 = Sm2CertUtils.getPublicKeyStrFromX509(publicKey);

        //获取请求头参数
        Map<String, String> headers = null;
        //请求体报文加密
        String encryptRequestBody = null;
        {
            headers = IsGateWayTestMain.getRequestHeaders();
            //请求头待签名文本
            final String headerSignText = IsGateWayTestMain.createSignContent(headers);
            //请求头签名,私钥签名
            final byte[] headerSignByte = Sm2Utils.sign(privateKeyStrFromPKCS8, headerSignText);
            //请求头凭证
            headers.put(RequestHeader.OPEN_SIGN, Hex.toHexString(headerSignByte));

            //请求体报文json字符串,业务数据
            final String requestBody = "{\"ccsOrgId\":\"cbf4e785-4dfd-4cd1-b789-dbd6a959843f\"}";
            //请求体报文加密
            encryptRequestBody = Sm2Utils.encrypt(publicKeyStrFromX509, requestBody);
        }

        //原始响应报文
        final IsGateWayHttpResponseBody isGateWayHttpResponseBody = IsGateWayHttpClientUtils.doHttpPost(basePath + resource, encryptRequestBody, headers);
        System.err.println("响应原报文：");
        System.err.println(isGateWayHttpResponseBody.getResponseBody());

        {
            //响应体解密
            final ResponseBody responseBody = IsGatewayApiResponseUtils.obtainResponse(isGateWayHttpResponseBody, privateKeyStrFromPKCS8);
            if (responseBody.isSuccess()) {
                System.out.println("响应参数业务节点解密后：");
                System.out.println(responseBody.getResultDetail());
            } else {
                System.err.println(responseBody.getMessage());
            }
            System.err.println("end===============================================================");
        }
    }
}